home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / bc-1_02.lha / bc-1.02 / scan.l < prev    next >
Text File  |  1992-03-04  |  5KB  |  190 lines

  1. %{
  2. /* scan.l: the (f)lex description file for the scanner. */
  3.  
  4. /*  This file is part of bc written for MINIX.
  5.     Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License , or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.     You may contact the author by:
  22.        e-mail:  phil@cs.wwu.edu
  23.       us-mail:  Philip A. Nelson
  24.                 Computer Science Department, 9062
  25.                 Western Washington University
  26.                 Bellingham, WA 98226-9062
  27.        
  28. *************************************************************************/
  29.  
  30. #include "bcdefs.h"
  31. #include "y.tab.h"
  32. #include "global.h"
  33. #include "proto.h"
  34.  
  35. /* Using flex, we can ask for a smaller input buffer.  With lex, this
  36.    does nothing! */
  37.  
  38. #ifdef SMALL_BUF
  39. #undef YY_READ_BUF_SIZE
  40. #define YY_READ_BUF_SIZE 512
  41. #endif
  42.  
  43. /* We want to define our own yywrap. */
  44. #undef yywrap
  45. _PROTOTYPE(int yywrap, (void));
  46.  
  47. /* MINIX returns from read with < 0 if SIGINT is  encountered.
  48.    In flex, we can redefine YY_INPUT to the following.  In lex, this
  49.    does nothing! */
  50. #include <errno.h>
  51. #undef  YY_INPUT
  52. #define YY_INPUT(buf,result,max_size) \
  53.     while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
  54.         if (errno != EINTR) \
  55.         YY_FATAL_ERROR( "read() in flex scanner failed" );
  56.  
  57. %}
  58. DIGIT [0-9A-F]
  59. LETTER [a-z]
  60. %%
  61. define return(Define);
  62. break  return(Break);
  63. quit   return(Quit);
  64. length return(Length);
  65. return return(Return);
  66. for    return(For);
  67. if     return(If);
  68. while  return(While);
  69. sqrt   return(Sqrt);
  70. scale  return(Scale);
  71. ibase  return(Ibase);
  72. obase  return(Obase);
  73. auto   return(Auto);
  74. else   return(Else);
  75. read   return(Read);
  76. halt   return(Halt);
  77. last   return(Last);
  78. warranty return(Warranty);
  79. continue return(Continue);
  80. print  return(Print);
  81. limits return(Limits);
  82. "+"|"-"|";"|"("|")"|"{"|"}"|"["|"]"|","|"^" { yylval.c_value = yytext[0]; 
  83.                           return((int)yytext[0]); }
  84. && { return(AND); }
  85. \|\| { return(OR); }
  86. "!" { return(NOT); }
  87. "*"|"/"|"%" { yylval.c_value = yytext[0]; return(MUL_OP); }
  88. "="|\+=|-=|\*=|\/=|%=|\^=  { yylval.c_value = yytext[0]; return(ASSIGN_OP); }
  89. =\+|=-|=\*|=\/|=%|=\^  { 
  90. #ifdef OLD_EQ_OP
  91.              char warn_save;
  92.              warn_save = warn_not_std;
  93.              warn_not_std = TRUE;
  94.              warn ("Old fashioned =<op>");
  95.              warn_not_std = warn_save;
  96.              yylval.c_value = yytext[1];
  97. #else
  98.              yylval.c_value = '=';
  99.              yyless (1);
  100. #endif
  101.              return(ASSIGN_OP);
  102.                }
  103. ==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof(yytext); return(REL_OP); }
  104. \+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); }
  105. "\n" { line_no++; return(NEWLINE); }
  106. \\\n {  line_no++;  /* ignore a "quoted" newline */ }
  107. [ \t]+  { /* ignore spaces and tabs */ }
  108. "/*"  {
  109.     int c;
  110.  
  111.     for (;;)
  112.       {
  113.         while ( ((c=input()) != '*') && (c != EOF)) 
  114.           /* eat it */
  115.           if (c == '\n') line_no++;
  116.         if (c == '*')
  117.            {
  118.         while ( (c=input()) == '*') /* eat it*/;
  119.         if (c == '/') break; /* at end of comment */
  120.         if (c == '\n') line_no++;
  121.           }
  122.         if (c == EOF)
  123.           {
  124.         fprintf (stderr,"EOF encountered in a comment.\n");
  125.         break;
  126.           }
  127.       }
  128.       }
  129. [a-z][a-z0-9_]* { yylval.s_value = strcopyof(yytext); return(NAME); }
  130. \"[^\"]*\"  {
  131.            unsigned char *look;
  132.           int count = 0;
  133.           yylval.s_value = strcopyof(yytext);
  134.           for (look = yytext; *look != 0; look++)
  135.         {
  136.           if (*look == '\n') line_no++;
  137.           if (*look == '"')  count++;
  138.         }
  139.           if (count != 2) yyerror ("NUL character in string.");
  140.           return(STRING);
  141.         }
  142. {DIGIT}({DIGIT}|\\\n)*("."({DIGIT}|\\\n)*)?|"."(\\\n)*{DIGIT}({DIGIT}|\\\n)* {
  143.           unsigned char *src, *dst;
  144.           int len;
  145.           /* remove a trailing decimal point. */
  146.           len = strlen(yytext);
  147.           if (yytext[len-1] == '.')
  148.             yytext[len-1] = 0;
  149.           /* remove leading zeros. */
  150.           src = yytext;
  151.           dst = yytext;
  152.           while (*src == '0') src++;
  153.           if (*src == 0) src--;
  154.           /* Copy strings removing the newlines. */
  155.           while (*src != 0)
  156.         {
  157.               if (*src == '\\')
  158.             {
  159.               src++; src++;
  160.               line_no++;
  161.             }
  162.           else
  163.             *dst++ = *src++;
  164.             }
  165.           *dst = 0;
  166.           yylval.s_value = strcopyof(yytext); 
  167.           return(NUMBER);
  168.         }
  169. .       {
  170.       if (yytext[0] < ' ')
  171.         yyerror ("illegal character: ^%c",yytext[0] + '@');
  172.       else
  173.         if (yytext[0] > '~')
  174.           yyerror ("illegal character: \\%3d", (int) yytext[0]);
  175.         else
  176.           yyerror ("illegal character: %s",yytext);
  177.     }
  178. %%
  179.  
  180.  
  181.  
  182. /* This is the way to get multiple files input into lex. */
  183.  
  184. int
  185. yywrap()
  186. {
  187.   if (!open_new_file ()) return (1);    /* EOF on standard in. */
  188.   return (0);                /* We have more input. */
  189. }
  190.